package airport.client.widget.hotel;

import airport.client.Airport;
import airport.client.utils.Constantes;
import airport.shared.beans.HotelBean;
import airport.shared.beans.UserBean;
import airport.shared.service.AirportService;
import airport.shared.service.AirportServiceAsync;
import airport.shared.service.HotelService;
import airport.shared.service.HotelServiceAsync;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.NumberCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;

import java.util.ArrayList;

/**
 * Created by François on 06/03/2015.
 */
public class HotelWB extends Airport {


	FlowPanel mainPanel = new FlowPanel();
	FlowPanel savePanel = new FlowPanel();
	FlowPanel consultPanel = new FlowPanel();
	FlowPanel updatePanel = new FlowPanel();
	FlowPanel flowPanel1 = new FlowPanel();
	FlowPanel flowPanel2 = new FlowPanel();
	FlowPanel panelG = new FlowPanel();
	FlowPanel panelD = new FlowPanel();
	FlowPanel panelB = new FlowPanel();
	FlowPanel panelBD = new FlowPanel();

    Label labelInformations = new Label("Informations Hôtel");
    Label labelStanding = new Label("Standing");


    ArrayList<HotelBean> hotels;
    CellTable<HotelBean> tab_hotels = new CellTable<>();
	ListDataProvider<HotelBean> ldp = new ListDataProvider<>();
	HotelBean selected_hotel;

    FlowPanel htmlSpan = new FlowPanel("span");


    Label label_titre = new Label();

	TextBox textbox_nom = new TextBox();
	TextBox textbox_adresse = new TextBox();
	DoubleBox doublebox_tarif = new DoubleBox();
	ListBox standing = standing();
	Button button_submit = new Button();
    Button button_retour = new Button();

	public HotelWB(int tabPanel) {
		initWidget(mainPanel);
		checkLogin(tabPanel);

	}

	public void checkLogin(final int tabPanel) {
		final AirportServiceAsync connexionIface;
		connexionIface = GWT.create(AirportService.class);

        connexionIface.checkLogin(new AsyncCallback<UserBean>() {

			@Override
			public void onFailure(Throwable caught) {
				infoDanger(caught.toString());
			}

			@Override
            public void onSuccess(UserBean result) {
                if (result != null) {
                    labelTitre.getElement().setInnerHTML("Bienvenue " + result.getPrenom() + " " + result.getNom());
                    htmlSpan.setStyleName("add-on");
                    htmlSpan.getElement().setInnerHTML("€");
                    switch (tabPanel) {
						case 1:
							loadHotels();
							break;
						case 2:
                            mainPanel.add(label_titre);
                            FlowPanel hr = new FlowPanel("hr");
                            mainPanel.add(hr);
							loadSavePanel();
							break;
						default:
							break;
					}
				} else {
					initbouton(false);
					History.newItem(Constantes.ACCUEILWB);
				}
			}
		});
	}

	private void loadSavePanel() {
		consultPanel.setVisible(false);
		savePanel.setVisible(true);
		updatePanel.setVisible(false);

		loadHotelForm(savePanel);

		label_titre.setText("Ajouter un hôtel");
		button_submit.setText("Enregistrer");
        button_retour.setVisible(false);
        addClickHandler_save(button_submit);
	}

	private void loadUpdatePanel() {
		consultPanel.setVisible(false);
		savePanel.setVisible(false);
		updatePanel.setVisible(true);

		loadHotelForm(updatePanel);
		label_titre.setText("Modifier un hotel");
		textbox_nom.setText(selected_hotel.getNom());
		textbox_adresse.setText(selected_hotel.getAdresse());
		doublebox_tarif.setValue(selected_hotel.getTarif().doubleValue());
		standing.setItemSelected(selected_hotel.getStanding() - 1, true);
		button_submit.setText("Mettre à jour");
        button_retour.setVisible(true);
        button_retour.setText("Retour");

	}

	private void save() {
        infoDangerHide();
        int stand = Integer.parseInt(standing.getSelectedValue());


        if (textbox_nom.getText().length() == 0
                || textbox_adresse.getText().length() == 0
                || stand == 0
                || doublebox_tarif.getText().length() == 0) {
            infoDanger("Informations incomplètes");
            return;
        }


        final HotelServiceAsync hotelIface;
        Float tarif = textboxToFloat(doublebox_tarif.getText());
        hotelIface = GWT.create(HotelService.class);

		hotelIface.save(textbox_nom.getText(), textbox_adresse.getText(), stand, tarif,
				new AsyncCallback<String>() {
					@Override
					public void onFailure(Throwable caught) {
						infoDanger(caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						infoSuccess(result);
						History.newItem(Constantes.HOTELCONSULTWB);
					}
				});
	}

	private void loadHotelForm(FlowPanel panel) {
		flowPanel1.setStyleName("row-fluid");
		flowPanel2.setStyleName("row-fluid");

		label_titre.setStyleName("nav-header");

        labelInformations.setStyleName("nav-header");
        flowPanel1.add(labelInformations);

		textbox_nom.setStyleName("textbox_gauche");
		textbox_nom.setHeight("30");
		textbox_nom.getElement().setPropertyString(Constantes.PLACEHOLDER, "Nom de l'hôtel");

		textbox_adresse.setStyleName("textbox_gauche");
		textbox_adresse.setHeight("30");
		textbox_adresse.getElement().setPropertyString(Constantes.PLACEHOLDER, "Adresse");

		standing.setStyleName("textbox_gauche");
		standing.getElement().setPropertyString(Constantes.PLACEHOLDER, "Standing");
		standing.setHeight("30");
		standing.setWidth("140");

		doublebox_tarif.setStyleName("textbox_tarif");
		doublebox_tarif.setHeight("30");
		doublebox_tarif.getElement().setPropertyString(Constantes.PLACEHOLDER, "Tarif");

		button_submit.setStyleName("btn spaced");
		button_submit.setHeight("30");
		button_submit.setWidth("140");

        button_retour.setStyleName("btn spaced");
        button_retour.setHeight("30");
        button_retour.setWidth("140");


        button_retour.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                consultPanel.setVisible(true);
                updatePanel.setVisible(false);
                label_titre.setText("Tous les hôtels");
            }
        });

		panelG.setStyleName("span4");
        panelG.add(textbox_nom);

		panelD.setStyleName("span4");
		panelD.add(textbox_adresse);

		panelB.setStyleName("span4");

        labelStanding.setStyleName("nav-header");
        flowPanel2.add(labelStanding);
        panelB.add(standing);

		panelBD.setStyleName("input-append");
        panelBD.add(htmlSpan);
        panelBD.add(doublebox_tarif);
		panelBD.add(htmlSpan);

		flowPanel1.add(panelG);
		flowPanel1.add(panelD);
		flowPanel2.add(panelB);
		flowPanel1.add(panelBD);

		panel.add(flowPanel1);
		panel.add(flowPanel2);
		panel.add(button_submit);
        panel.add(button_retour);


        mainPanel.add(panel);
    }

	private void loadConsultPanel() {
		label_titre.setStyleName("nav-header");
		label_titre.setText("Tous les hôtels");

		tab_hotels.setStyleName("table table-bordered");
		addColumns(tab_hotels);

		SimplePager pager = new SimplePager();
		pager.setDisplay(tab_hotels);
		pager.setPageSize(6);

		consultPanel.add(tab_hotels);
		consultPanel.add(pager);
		mainPanel.add(consultPanel);
	}

	private void loadHotels() {
		consultPanel.setVisible(true);
		savePanel.setVisible(false);
		updatePanel.setVisible(false);

		final HotelServiceAsync hotelIface;
		hotelIface = GWT.create(HotelService.class);

		infoDangerHide();
		hotelIface.selectAll(new AsyncCallback<ArrayList<HotelBean>>() {
			@Override
			public void onFailure(Throwable caught) {
				infoDanger(caught.toString());
			}

			@Override
			public void onSuccess(ArrayList<HotelBean> result) {
                mainPanel.add(label_titre);
                FlowPanel hr = new FlowPanel("hr");
                mainPanel.add(hr);
                hotels = result;
				addClickHandler_update(button_submit);
				loadConsultPanel();
			}
		});
	}

	private void addColumns(CellTable tab_vols) {
		Column<HotelBean, String> nom_column = new Column<HotelBean, String>(new TextCell()) {
			@Override
			public String getValue(HotelBean hotel) {
				return hotel.getNom();
			}
		};
		tab_hotels.addColumn(nom_column, "Nom");

		Column<HotelBean, String> adresse_column = new Column<HotelBean, String>(new TextCell()) {
			@Override
			public String getValue(HotelBean hotel) {
				return hotel.getAdresse();
			}
		};
		tab_hotels.addColumn(adresse_column, "Adresse");

        Column<HotelBean, String> standing_column = new Column<HotelBean, String>(new TextCell()) {
            @Override
            public String getValue(HotelBean hotel) {
                String leString = "";
                for (int i = 0; i < hotel.getStanding(); i++) {
                    leString += "★";
                }
                return leString;
            }
		};
		tab_hotels.addColumn(standing_column, "Standing");

		Column<HotelBean, Number> tarif_column = new Column<HotelBean, Number>(new NumberCell()) {
			@Override
			public Float getValue(HotelBean hotel) {
				return hotel.getTarif();
			}
		};
		tab_hotels.addColumn(tarif_column, "Tarif (€)");

		// Bouton editer

        ButtonCell editButton = new ButtonCell() {
            // A native button cell doesn't have the gwt-button class, which makes it
            // look weird next to other gwt buttons. Fix that here.
            @Override
            public void render(
                    final Context context,
                    final SafeHtml data,
                    final SafeHtmlBuilder sb) {
                sb.appendHtmlConstant("<button type=\"button\" class=\"btn btn-default\" tabindex=\"0\">");
                sb.appendHtmlConstant("<span class=\"icon-pencil\"></span>");
                sb.appendHtmlConstant("</button>");
            }
        };

        Column<HotelBean, String> action_edit_column = new Column<HotelBean, String>(editButton) {
            @Override
			public String getValue(HotelBean object) {
				return "~";
			}
		};
		action_edit_column.setFieldUpdater(new FieldUpdater<HotelBean, String>() {
            @Override
            public void update(int index, HotelBean hotelBean, String value) {
                infoDangerHide();
                selected_hotel = hotelBean;
                consultPanel.setVisible(false);
                savePanel.setVisible(false);
                updatePanel.setVisible(true);
                loadUpdatePanel();
            }
        });
        tab_hotels.addColumn(action_edit_column, "Editer");

        // Bouton supprimer
        ButtonCell supprimeButton = new ButtonCell() {
            // A native button cell doesn't have the gwt-button class, which makes it
            // look weird next to other gwt buttons. Fix that here.
            @Override
            public void render(
                    final Context context,
                    final SafeHtml data,
                    final SafeHtmlBuilder sb) {
                sb.appendHtmlConstant("<center><button type=\"button\" class=\"btn btn-danger\" tabindex=\"0\">");
                sb.appendHtmlConstant("<span class=\"icon-white icon-trash\"></span>");
                sb.appendHtmlConstant("</button></center>");
            }
        };

        Column<HotelBean, String> action_delete_column = new Column<HotelBean, String>(supprimeButton) {
            @Override
            public String getValue(HotelBean object) {
				return "x";
			}
		};

		action_delete_column.setFieldUpdater(new FieldUpdater<HotelBean, String>() {
            @Override
            public void update(int index, HotelBean hotelBean, String value) {
                if (hotelBean.getPanneaux() == 0) {
                    delete(hotelBean, index);
                } else {
                    infoDanger("appartient a un panneau");
                }
            }
        });

        tab_hotels.addColumnStyleName(tab_hotels.getColumnCount() - 1, "action-cell");
        tab_hotels.addColumnStyleName(tab_hotels.getColumnCount(), "action-cell");
        tab_hotels.addColumn(action_delete_column, "Supprimer");
        tab_hotels.setRowCount(hotels.size(), true);
		tab_hotels.setRowData(0, hotels);

		ldp.addDataDisplay(tab_hotels);
		ldp.setList(hotels);
	}

	private ListBox standing() {
		ListBox lb = new ListBox();

		lb.addItem("★", "1");
		lb.addItem("★★", "2");
		lb.addItem("★★★", "3");
		lb.addItem("★★★★", "4");
		lb.addItem("★★★★★", "5");

		lb.setSelectedIndex(2);

		return lb;
	}

	private void addClickHandler_save(Button button) {
		button.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				save();
			}
		});
	}

	private void addClickHandler_update(Button button) {
		button.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				update();
			}
		});
	}

	private void update() {
        infoDangerHide();
        int stand = Integer.parseInt(standing.getSelectedValue());

        if (textbox_nom.getText().length() == 0
                || textbox_adresse.getText().length() == 0
                || stand == 0
                || doublebox_tarif.getText().length() == 0) {
            infoDanger("Informations incomplètes");
            return;
        }
        Float tarif = textboxToFloat(doublebox_tarif.getText());
        selected_hotel.setNom(textbox_nom.getText());
        selected_hotel.setAdresse(textbox_adresse.getText());
        selected_hotel.setStanding(stand);
        selected_hotel.setTarif(tarif);

		final HotelServiceAsync hotelIface;
		hotelIface = GWT.create(HotelService.class);

		hotelIface.update(selected_hotel,
				new AsyncCallback<String>() {
					@Override
					public void onFailure(Throwable caught) {
						infoDanger(caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						infoSuccess(result);
						consultPanel.setVisible(true);
						updatePanel.setVisible(false);
						tab_hotels.redraw();
						label_titre.setText("Tous les hôtels");
					}
				});
	}

    private void delete(HotelBean hotelBean, final int index) {
        infoDangerHide();
        final HotelServiceAsync hotelIface;
		hotelIface = GWT.create(HotelService.class);

		hotelIface.delete(hotelBean,
				new AsyncCallback<String>() {
					@Override
					public void onFailure(Throwable caught) {
						infoDanger(caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						infoSuccess(result);
                        ldp.getList().remove(index);
                        ldp.refresh();
                        tab_hotels.redraw();
                    }
				});
	}

	private Float textboxToFloat(String textbox) {
		return new Float(textbox.replace(",", "."));
	}
}

